home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / flex_2_3 / part05 < prev    next >
Encoding:
Internet Message Format  |  1990-08-19  |  55.2 KB

  1. Path: abcfd20.larc.nasa.gov!amiga-request
  2. From: amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v90i232: flex 2.3 - fast lexical analyzer generator, Part05/13
  4. Reply-To: loftus@wpllabs.uucp (William P Loftus)
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga:v90i232@abcfd20.larc.nasa.gov>
  7. Date: 19 Aug 90 22:42:32 GMT
  8. Approved: tadguy@uunet.UU.NET (Tad Guy)
  9. X-Mail-Submissions-To: amiga@uunet.uu.net
  10. X-Post-Discussions-To: comp.sys.amiga
  11.  
  12. Submitted-by: loftus@wpllabs.uucp (William P Loftus)
  13. Posting-number: Volume 90, Issue 232
  14. Archive-name: unix/flex-2.3/part05
  15.  
  16. #!/bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of archive 5 (of 13)."
  23. # Contents:  dfa.c flex.Doc
  24. # Wrapped by tadguy@abcfd20 on Sun Aug 19 18:41:44 1990
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'dfa.c' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'dfa.c'\"
  28. else
  29. echo shar: Extracting \"'dfa.c'\" \(26919 characters\)
  30. sed "s/^X//" >'dfa.c' <<'END_OF_FILE'
  31. X/* dfa - DFA construction routines */
  32. X
  33. X/*-
  34. X * Copyright (c) 1990 The Regents of the University of California.
  35. X * All rights reserved.
  36. X *
  37. X * This code is derived from software contributed to Berkeley by
  38. X * Vern Paxson.
  39. X * 
  40. X * The United States Government has rights in this work pursuant
  41. X * to contract no. DE-AC03-76SF00098 between the United States
  42. X * Department of Energy and the University of California.
  43. X *
  44. X * Redistribution and use in source and binary forms are permitted provided
  45. X * that: (1) source distributions retain this entire copyright notice and
  46. X * comment, and (2) distributions including binaries display the following
  47. X * acknowledgement:  ``This product includes software developed by the
  48. X * University of California, Berkeley and its contributors'' in the
  49. X * documentation or other materials provided with the distribution and in
  50. X * all advertising materials mentioning features or use of this software.
  51. X * Neither the name of the University nor the names of its contributors may
  52. X * be used to endorse or promote products derived from this software without
  53. X * specific prior written permission.
  54. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  55. X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  56. X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  57. X */
  58. X
  59. X#ifndef lint
  60. Xstatic char rcsid[] =
  61. X    "@(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/dfa.c,v 2.7 90/06/27 23:48:15 vern Exp $ (LBL)";
  62. X#endif
  63. X
  64. X#include "flexdef.h"
  65. X
  66. X
  67. X/* declare functions that have forward references */
  68. X
  69. Xvoid dump_associated_rules PROTO((FILE*, int));
  70. Xvoid dump_transitions PROTO((FILE*, int[]));
  71. Xvoid sympartition PROTO((int[], int, int[], int[]));
  72. Xint symfollowset PROTO((int[], int, int, int[]));
  73. X
  74. X
  75. X/* check_for_backtracking - check a DFA state for backtracking
  76. X *
  77. X * synopsis
  78. X *     int ds, state[numecs];
  79. X *     check_for_backtracking( ds, state );
  80. X *
  81. X * ds is the number of the state to check and state[] is its out-transitions,
  82. X * indexed by equivalence class, and state_rules[] is the set of rules
  83. X * associated with this state
  84. X */
  85. X
  86. Xvoid check_for_backtracking( ds, state )
  87. Xint ds;
  88. Xint state[];
  89. X
  90. X    {
  91. X    if ( (reject && ! dfaacc[ds].dfaacc_set) || ! dfaacc[ds].dfaacc_state )
  92. X    { /* state is non-accepting */
  93. X    ++num_backtracking;
  94. X
  95. X    if ( backtrack_report )
  96. X        {
  97. X        fprintf( backtrack_file, "State #%d is non-accepting -\n", ds );
  98. X
  99. X        /* identify the state */
  100. X        dump_associated_rules( backtrack_file, ds );
  101. X
  102. X        /* now identify it further using the out- and jam-transitions */
  103. X        dump_transitions( backtrack_file, state );
  104. X
  105. X        putc( '\n', backtrack_file );
  106. X        }
  107. X    }
  108. X    }
  109. X
  110. X
  111. X/* check_trailing_context - check to see if NFA state set constitutes
  112. X *                          "dangerous" trailing context
  113. X *
  114. X * synopsis
  115. X *    int nfa_states[num_states+1], num_states;
  116. X *    int accset[nacc+1], nacc;
  117. X *    check_trailing_context( nfa_states, num_states, accset, nacc );
  118. X *
  119. X * NOTES
  120. X *    Trailing context is "dangerous" if both the head and the trailing
  121. X *  part are of variable size \and/ there's a DFA state which contains
  122. X *  both an accepting state for the head part of the rule and NFA states
  123. X *  which occur after the beginning of the trailing context.
  124. X *  When such a rule is matched, it's impossible to tell if having been
  125. X *  in the DFA state indicates the beginning of the trailing context
  126. X *  or further-along scanning of the pattern.  In these cases, a warning
  127. X *  message is issued.
  128. X *
  129. X *    nfa_states[1 .. num_states] is the list of NFA states in the DFA.
  130. X *    accset[1 .. nacc] is the list of accepting numbers for the DFA state.
  131. X */
  132. X
  133. Xvoid check_trailing_context( nfa_states, num_states, accset, nacc )
  134. Xint *nfa_states, num_states;
  135. Xint *accset;
  136. Xregister int nacc;
  137. X
  138. X    {
  139. X    register int i, j;
  140. X
  141. X    for ( i = 1; i <= num_states; ++i )
  142. X    {
  143. X    int ns = nfa_states[i];
  144. X    register int type = state_type[ns];
  145. X    register int ar = assoc_rule[ns];
  146. X
  147. X    if ( type == STATE_NORMAL || rule_type[ar] != RULE_VARIABLE )
  148. X        { /* do nothing */
  149. X        }
  150. X
  151. X    else if ( type == STATE_TRAILING_CONTEXT )
  152. X        {
  153. X        /* potential trouble.  Scan set of accepting numbers for
  154. X         * the one marking the end of the "head".  We assume that
  155. X         * this looping will be fairly cheap since it's rare that
  156. X         * an accepting number set is large.
  157. X         */
  158. X        for ( j = 1; j <= nacc; ++j )
  159. X        if ( accset[j] & YY_TRAILING_HEAD_MASK )
  160. X            {
  161. X            fprintf( stderr,
  162. X             "%s: Dangerous trailing context in rule at line %d\n",
  163. X                 program_name, rule_linenum[ar] );
  164. X            return;
  165. X            }
  166. X        }
  167. X    }
  168. X    }
  169. X
  170. X
  171. X/* dump_associated_rules - list the rules associated with a DFA state
  172. X *
  173. X * synopisis
  174. X *     int ds;
  175. X *     FILE *file;
  176. X *     dump_associated_rules( file, ds );
  177. X *
  178. X * goes through the set of NFA states associated with the DFA and
  179. X * extracts the first MAX_ASSOC_RULES unique rules, sorts them,
  180. X * and writes a report to the given file
  181. X */
  182. X
  183. Xvoid dump_associated_rules( file, ds )
  184. XFILE *file;
  185. Xint ds;
  186. X
  187. X    {
  188. X    register int i, j;
  189. X    register int num_associated_rules = 0;
  190. X    int rule_set[MAX_ASSOC_RULES + 1];
  191. X    int *dset = dss[ds];
  192. X    int size = dfasiz[ds];
  193. X    
  194. X    for ( i = 1; i <= size; ++i )
  195. X    {
  196. X    register rule_num = rule_linenum[assoc_rule[dset[i]]];
  197. X
  198. X    for ( j = 1; j <= num_associated_rules; ++j )
  199. X        if ( rule_num == rule_set[j] )
  200. X        break;
  201. X
  202. X    if ( j > num_associated_rules )
  203. X        { /* new rule */
  204. X        if ( num_associated_rules < MAX_ASSOC_RULES )
  205. X        rule_set[++num_associated_rules] = rule_num;
  206. X        }
  207. X    }
  208. X
  209. X    bubble( rule_set, num_associated_rules );
  210. X
  211. X    fprintf( file, " associated rule line numbers:" );
  212. X
  213. X    for ( i = 1; i <= num_associated_rules; ++i )
  214. X    {
  215. X    if ( i % 8 == 1 )
  216. X        putc( '\n', file );
  217. X    
  218. X    fprintf( file, "\t%d", rule_set[i] );
  219. X    }
  220. X    
  221. X    putc( '\n', file );
  222. X    }
  223. X
  224. X
  225. X/* dump_transitions - list the transitions associated with a DFA state
  226. X *
  227. X * synopisis
  228. X *     int state[numecs];
  229. X *     FILE *file;
  230. X *     dump_transitions( file, state );
  231. X *
  232. X * goes through the set of out-transitions and lists them in human-readable
  233. X * form (i.e., not as equivalence classes); also lists jam transitions
  234. X * (i.e., all those which are not out-transitions, plus EOF).  The dump
  235. X * is done to the given file.
  236. X */
  237. X
  238. Xvoid dump_transitions( file, state )
  239. XFILE *file;
  240. Xint state[];
  241. X
  242. X    {
  243. X    register int i, ec;
  244. X    int out_char_set[CSIZE];
  245. X
  246. X    for ( i = 0; i < csize; ++i )
  247. X    {
  248. X    ec = abs( ecgroup[i] );
  249. X    out_char_set[i] = state[ec];
  250. X    }
  251. X    
  252. X    fprintf( file, " out-transitions: " );
  253. X
  254. X    list_character_set( file, out_char_set );
  255. X
  256. X    /* now invert the members of the set to get the jam transitions */
  257. X    for ( i = 0; i < csize; ++i )
  258. X    out_char_set[i] = ! out_char_set[i];
  259. X
  260. X    fprintf( file, "\n jam-transitions: EOF " );
  261. X
  262. X    list_character_set( file, out_char_set );
  263. X
  264. X    putc( '\n', file );
  265. X    }
  266. X
  267. X
  268. X/* epsclosure - construct the epsilon closure of a set of ndfa states
  269. X *
  270. X * synopsis
  271. X *    int t[current_max_dfa_size], numstates, accset[num_rules + 1], nacc;
  272. X *    int hashval;
  273. X *    int *epsclosure();
  274. X *    t = epsclosure( t, &numstates, accset, &nacc, &hashval );
  275. X *
  276. X * NOTES
  277. X *    the epsilon closure is the set of all states reachable by an arbitrary
  278. X *  number of epsilon transitions which themselves do not have epsilon
  279. X *  transitions going out, unioned with the set of states which have non-null
  280. X *  accepting numbers.  t is an array of size numstates of nfa state numbers.
  281. X *  Upon return, t holds the epsilon closure and numstates is updated.  accset
  282. X *  holds a list of the accepting numbers, and the size of accset is given
  283. X *  by nacc.  t may be subjected to reallocation if it is not large enough
  284. X *  to hold the epsilon closure.
  285. X *
  286. X *    hashval is the hash value for the dfa corresponding to the state set
  287. X */
  288. X
  289. Xint *epsclosure( t, ns_addr, accset, nacc_addr, hv_addr )
  290. Xint *t, *ns_addr, accset[], *nacc_addr, *hv_addr;
  291. X
  292. X    {
  293. X    register int stkpos, ns, tsp;
  294. X    int numstates = *ns_addr, nacc, hashval, transsym, nfaccnum;
  295. X    int stkend, nstate;
  296. X    static int did_stk_init = false, *stk; 
  297. X
  298. X#define MARK_STATE(state) \
  299. X    trans1[state] = trans1[state] - MARKER_DIFFERENCE;
  300. X
  301. X#define IS_MARKED(state) (trans1[state] < 0)
  302. X
  303. X#define UNMARK_STATE(state) \
  304. X    trans1[state] = trans1[state] + MARKER_DIFFERENCE;
  305. X
  306. X#define CHECK_ACCEPT(state) \
  307. X    { \
  308. X    nfaccnum = accptnum[state]; \
  309. X    if ( nfaccnum != NIL ) \
  310. X        accset[++nacc] = nfaccnum; \
  311. X    }
  312. X
  313. X#define DO_REALLOCATION \
  314. X    { \
  315. X    current_max_dfa_size += MAX_DFA_SIZE_INCREMENT; \
  316. X    ++num_reallocs; \
  317. X    t = reallocate_integer_array( t, current_max_dfa_size ); \
  318. X    stk = reallocate_integer_array( stk, current_max_dfa_size ); \
  319. X    } \
  320. X
  321. X#define PUT_ON_STACK(state) \
  322. X    { \
  323. X    if ( ++stkend >= current_max_dfa_size ) \
  324. X        DO_REALLOCATION \
  325. X    stk[stkend] = state; \
  326. X    MARK_STATE(state) \
  327. X    }
  328. X
  329. X#define ADD_STATE(state) \
  330. X    { \
  331. X    if ( ++numstates >= current_max_dfa_size ) \
  332. X        DO_REALLOCATION \
  333. X    t[numstates] = state; \
  334. X    hashval = hashval + state; \
  335. X    }
  336. X
  337. X#define STACK_STATE(state) \
  338. X    { \
  339. X    PUT_ON_STACK(state) \
  340. X    CHECK_ACCEPT(state) \
  341. X    if ( nfaccnum != NIL || transchar[state] != SYM_EPSILON ) \
  342. X        ADD_STATE(state) \
  343. X    }
  344. X
  345. X    if ( ! did_stk_init )
  346. X    {
  347. X    stk = allocate_integer_array( current_max_dfa_size );
  348. X    did_stk_init = true;
  349. X    }
  350. X
  351. X    nacc = stkend = hashval = 0;
  352. X
  353. X    for ( nstate = 1; nstate <= numstates; ++nstate )
  354. X    {
  355. X    ns = t[nstate];
  356. X
  357. X    /* the state could be marked if we've already pushed it onto
  358. X     * the stack
  359. X     */
  360. X    if ( ! IS_MARKED(ns) )
  361. X        PUT_ON_STACK(ns)
  362. X
  363. X    CHECK_ACCEPT(ns)
  364. X    hashval = hashval + ns;
  365. X    }
  366. X
  367. X    for ( stkpos = 1; stkpos <= stkend; ++stkpos )
  368. X    {
  369. X    ns = stk[stkpos];
  370. X    transsym = transchar[ns];
  371. X
  372. X    if ( transsym == SYM_EPSILON )
  373. X        {
  374. X        tsp = trans1[ns] + MARKER_DIFFERENCE;
  375. X
  376. X        if ( tsp != NO_TRANSITION )
  377. X        {
  378. X        if ( ! IS_MARKED(tsp) )
  379. X            STACK_STATE(tsp)
  380. X
  381. X        tsp = trans2[ns];
  382. X
  383. X        if ( tsp != NO_TRANSITION )
  384. X            if ( ! IS_MARKED(tsp) )
  385. X            STACK_STATE(tsp)
  386. X        }
  387. X        }
  388. X    }
  389. X
  390. X    /* clear out "visit" markers */
  391. X
  392. X    for ( stkpos = 1; stkpos <= stkend; ++stkpos )
  393. X    {
  394. X    if ( IS_MARKED(stk[stkpos]) )
  395. X        {
  396. X        UNMARK_STATE(stk[stkpos])
  397. X        }
  398. X    else
  399. X        flexfatal( "consistency check failed in epsclosure()" );
  400. X    }
  401. X
  402. X    *ns_addr = numstates;
  403. X    *hv_addr = hashval;
  404. X    *nacc_addr = nacc;
  405. X
  406. X    return ( t );
  407. X    }
  408. X
  409. X
  410. X/* increase_max_dfas - increase the maximum number of DFAs */
  411. X
  412. Xvoid increase_max_dfas()
  413. X
  414. X    {
  415. X    current_max_dfas += MAX_DFAS_INCREMENT;
  416. X
  417. X    ++num_reallocs;
  418. X
  419. X    base = reallocate_integer_array( base, current_max_dfas );
  420. X    def = reallocate_integer_array( def, current_max_dfas );
  421. X    dfasiz = reallocate_integer_array( dfasiz, current_max_dfas );
  422. X    accsiz = reallocate_integer_array( accsiz, current_max_dfas );
  423. X    dhash = reallocate_integer_array( dhash, current_max_dfas );
  424. X    dss = reallocate_int_ptr_array( dss, current_max_dfas );
  425. X    dfaacc = reallocate_dfaacc_union( dfaacc, current_max_dfas );
  426. X
  427. X    if ( nultrans )
  428. X    nultrans = reallocate_integer_array( nultrans, current_max_dfas );
  429. X    }
  430. X
  431. X
  432. X/* ntod - convert an ndfa to a dfa
  433. X *
  434. X * synopsis
  435. X *    ntod();
  436. X *
  437. X *  creates the dfa corresponding to the ndfa we've constructed.  the
  438. X *  dfa starts out in state #1.
  439. X */
  440. X
  441. Xvoid ntod()
  442. X
  443. X    {
  444. X    int *accset, ds, nacc, newds;
  445. X    int sym, hashval, numstates, dsize;
  446. X    int num_full_table_rows;    /* used only for -f */
  447. X    int *nset, *dset;
  448. X    int targptr, totaltrans, i, comstate, comfreq, targ;
  449. X    int *epsclosure(), snstods(), symlist[CSIZE + 1];
  450. X    int num_start_states;
  451. X    int todo_head, todo_next;
  452. X
  453. X    /* note that the following are indexed by *equivalence classes*
  454. X     * and not by characters.  Since equivalence classes are indexed
  455. X     * beginning with 1, even if the scanner accepts NUL's, this
  456. X     * means that (since every character is potentially in its own
  457. X     * equivalence class) these arrays must have room for indices
  458. X     * from 1 to CSIZE, so their size must be CSIZE + 1.
  459. X     */
  460. X    int duplist[CSIZE + 1], state[CSIZE + 1];
  461. X    int targfreq[CSIZE + 1], targstate[CSIZE + 1];
  462. X
  463. X    /* this is so find_table_space(...) will know where to start looking in
  464. X     * chk/nxt for unused records for space to put in the state
  465. X     */
  466. X    if ( fullspd )
  467. X    firstfree = 0;
  468. X
  469. X    accset = allocate_integer_array( num_rules + 1 );
  470. X    nset = allocate_integer_array( current_max_dfa_size );
  471. X
  472. X    /* the "todo" queue is represented by the head, which is the DFA
  473. X     * state currently being processed, and the "next", which is the
  474. X     * next DFA state number available (not in use).  We depend on the
  475. X     * fact that snstods() returns DFA's \in increasing order/, and thus
  476. X     * need only know the bounds of the dfas to be processed.
  477. X     */
  478. X    todo_head = todo_next = 0;
  479. X
  480. X    for ( i = 0; i <= csize; ++i )
  481. X    {
  482. X    duplist[i] = NIL;
  483. X    symlist[i] = false;
  484. X    }
  485. X
  486. X    for ( i = 0; i <= num_rules; ++i )
  487. X    accset[i] = NIL;
  488. X
  489. X    if ( trace )
  490. X    {
  491. X    dumpnfa( scset[1] );
  492. X    fputs( "\n\nDFA Dump:\n\n", stderr );
  493. X    }
  494. X
  495. X    inittbl();
  496. X
  497. X    /* check to see whether we should build a separate table for transitions
  498. X     * on NUL characters.  We don't do this for full-speed (-F) scanners,
  499. X     * since for them we don't have a simple state number lying around with
  500. X     * which to index the table.  We also don't bother doing it for scanners
  501. X     * unless (1) NUL is in its own equivalence class (indicated by a
  502. X     * positive value of ecgroup[NUL]), (2) NUL's equilvalence class is
  503. X     * the last equivalence class, and (3) the number of equivalence classes
  504. X     * is the same as the number of characters.  This latter case comes about
  505. X     * when useecs is false or when its true but every character still
  506. X     * manages to land in its own class (unlikely, but it's cheap to check
  507. X     * for).  If all these things are true then the character code needed
  508. X     * to represent NUL's equivalence class for indexing the tables is
  509. X     * going to take one more bit than the number of characters, and therefore
  510. X     * we won't be assured of being able to fit it into a YY_CHAR variable.
  511. X     * This rules out storing the transitions in a compressed table, since
  512. X     * the code for interpreting them uses a YY_CHAR variable (perhaps it
  513. X     * should just use an integer, though; this is worth pondering ... ###).
  514. X     *
  515. X     * Finally, for full tables, we want the number of entries in the
  516. X     * table to be a power of two so the array references go fast (it
  517. X     * will just take a shift to compute the major index).  If encoding
  518. X     * NUL's transitions in the table will spoil this, we give it its
  519. X     * own table (note that this will be the case if we're not using
  520. X     * equivalence classes).
  521. X     */
  522. X
  523. X    /* note that the test for ecgroup[0] == numecs below accomplishes
  524. X     * both (1) and (2) above
  525. X     */
  526. X    if ( ! fullspd && ecgroup[0] == numecs )
  527. X    { /* NUL is alone in its equivalence class, which is the last one */
  528. X    int use_NUL_table = (numecs == csize);
  529. X
  530. X    if ( fulltbl && ! use_NUL_table )
  531. X        { /* we still may want to use the table if numecs is a power of 2 */
  532. X        int power_of_two;
  533. X
  534. X        for ( power_of_two = 1; power_of_two <= csize; power_of_two *= 2 )
  535. X        if ( numecs == power_of_two )
  536. X            {
  537. X            use_NUL_table = true;
  538. X            break;
  539. X            }
  540. X        }
  541. X
  542. X    if ( use_NUL_table )
  543. X        nultrans = allocate_integer_array( current_max_dfas );
  544. X        /* from now on, nultrans != nil indicates that we're
  545. X         * saving null transitions for later, separate encoding
  546. X         */
  547. X    }
  548. X
  549. X
  550. X    if ( fullspd )
  551. X    {
  552. X    for ( i = 0; i <= numecs; ++i )
  553. X        state[i] = 0;
  554. X    place_state( state, 0, 0 );
  555. X    }
  556. X
  557. X    else if ( fulltbl )
  558. X    {
  559. X    if ( nultrans )
  560. X        /* we won't be including NUL's transitions in the table,
  561. X         * so build it for entries from 0 .. numecs - 1
  562. X         */
  563. X        num_full_table_rows = numecs;
  564. X
  565. X    else
  566. X        /* take into account the fact that we'll be including
  567. X         * the NUL entries in the transition table.  Build it
  568. X         * from 0 .. numecs.
  569. X         */
  570. X        num_full_table_rows = numecs + 1;
  571. X
  572. X    /* declare it "short" because it's a real long-shot that that
  573. X     * won't be large enough.
  574. X     */
  575. X    printf( "static short int yy_nxt[][%d] =\n    {\n",
  576. X        /* '}' so vi doesn't get too confused */
  577. X        num_full_table_rows );
  578. X
  579. X    /* generate 0 entries for state #0 */
  580. X    for ( i = 0; i < num_full_table_rows; ++i )
  581. X        mk2data( 0 );
  582. X
  583. X    /* force ',' and dataflush() next call to mk2data */
  584. X    datapos = NUMDATAITEMS;
  585. X
  586. X    /* force extra blank line next dataflush() */
  587. X    dataline = NUMDATALINES;
  588. X    }
  589. X
  590. X    /* create the first states */
  591. X
  592. X    num_start_states = lastsc * 2;
  593. X
  594. X    for ( i = 1; i <= num_start_states; ++i )
  595. X    {
  596. X    numstates = 1;
  597. X
  598. X    /* for each start condition, make one state for the case when
  599. X     * we're at the beginning of the line (the '%' operator) and
  600. X     * one for the case when we're not
  601. X     */
  602. X    if ( i % 2 == 1 )
  603. X        nset[numstates] = scset[(i / 2) + 1];
  604. X    else
  605. X        nset[numstates] = mkbranch( scbol[i / 2], scset[i / 2] );
  606. X
  607. X    nset = epsclosure( nset, &numstates, accset, &nacc, &hashval );
  608. X
  609. X    if ( snstods( nset, numstates, accset, nacc, hashval, &ds ) )
  610. X        {
  611. X        numas += nacc;
  612. X        totnst += numstates;
  613. X        ++todo_next;
  614. X
  615. X        if ( variable_trailing_context_rules && nacc > 0 )
  616. X        check_trailing_context( nset, numstates, accset, nacc );
  617. X        }
  618. X    }
  619. X
  620. X    if ( ! fullspd )
  621. X    {
  622. X    if ( ! snstods( nset, 0, accset, 0, 0, &end_of_buffer_state ) )
  623. X        flexfatal( "could not create unique end-of-buffer state" );
  624. X
  625. X    ++numas;
  626. X    ++num_start_states;
  627. X    ++todo_next;
  628. X    }
  629. X
  630. X    while ( todo_head < todo_next )
  631. X    {
  632. X    targptr = 0;
  633. X    totaltrans = 0;
  634. X
  635. X    for ( i = 1; i <= numecs; ++i )
  636. X        state[i] = 0;
  637. X
  638. X    ds = ++todo_head;
  639. X
  640. X    dset = dss[ds];
  641. X    dsize = dfasiz[ds];
  642. X
  643. X    if ( trace )
  644. X        fprintf( stderr, "state # %d:\n", ds );
  645. X
  646. X    sympartition( dset, dsize, symlist, duplist );
  647. X
  648. X    for ( sym = 1; sym <= numecs; ++sym )
  649. X        {
  650. X        if ( symlist[sym] )
  651. X        {
  652. X        symlist[sym] = 0;
  653. X
  654. X        if ( duplist[sym] == NIL )
  655. X            { /* symbol has unique out-transitions */
  656. X            numstates = symfollowset( dset, dsize, sym, nset );
  657. X            nset = epsclosure( nset, &numstates, accset,
  658. X                       &nacc, &hashval );
  659. X
  660. X            if ( snstods( nset, numstates, accset,
  661. X                  nacc, hashval, &newds ) )
  662. X            {
  663. X            totnst = totnst + numstates;
  664. X            ++todo_next;
  665. X            numas += nacc;
  666. X
  667. X            if ( variable_trailing_context_rules && nacc > 0 )
  668. X                check_trailing_context( nset, numstates,
  669. X                accset, nacc );
  670. X            }
  671. X
  672. X            state[sym] = newds;
  673. X
  674. X            if ( trace )
  675. X            fprintf( stderr, "\t%d\t%d\n", sym, newds );
  676. X
  677. X            targfreq[++targptr] = 1;
  678. X            targstate[targptr] = newds;
  679. X            ++numuniq;
  680. X            }
  681. X
  682. X        else
  683. X            {
  684. X            /* sym's equivalence class has the same transitions
  685. X             * as duplist(sym)'s equivalence class
  686. X             */
  687. X            targ = state[duplist[sym]];
  688. X            state[sym] = targ;
  689. X
  690. X            if ( trace )
  691. X            fprintf( stderr, "\t%d\t%d\n", sym, targ );
  692. X
  693. X            /* update frequency count for destination state */
  694. X
  695. X            i = 0;
  696. X            while ( targstate[++i] != targ )
  697. X            ;
  698. X
  699. X            ++targfreq[i];
  700. X            ++numdup;
  701. X            }
  702. X
  703. X        ++totaltrans;
  704. X        duplist[sym] = NIL;
  705. X        }
  706. X        }
  707. X
  708. X    numsnpairs = numsnpairs + totaltrans;
  709. X
  710. X    if ( caseins && ! useecs )
  711. X        {
  712. X        register int j;
  713. X
  714. X        for ( i = 'A', j = 'a'; i <= 'Z'; ++i, ++j )
  715. X        state[i] = state[j];
  716. X        }
  717. X
  718. X    if ( ds > num_start_states )
  719. X        check_for_backtracking( ds, state );
  720. X
  721. X    if ( nultrans )
  722. X        {
  723. X        nultrans[ds] = state[NUL_ec];
  724. X        state[NUL_ec] = 0;    /* remove transition */
  725. X        }
  726. X
  727. X    if ( fulltbl )
  728. X        {
  729. X        /* supply array's 0-element */
  730. X        if ( ds == end_of_buffer_state )
  731. X        mk2data( -end_of_buffer_state );
  732. X        else
  733. X        mk2data( end_of_buffer_state );
  734. X
  735. X        for ( i = 1; i < num_full_table_rows; ++i )
  736. X        /* jams are marked by negative of state number */
  737. X        mk2data( state[i] ? state[i] : -ds );
  738. X
  739. X        /* force ',' and dataflush() next call to mk2data */
  740. X        datapos = NUMDATAITEMS;
  741. X
  742. X        /* force extra blank line next dataflush() */
  743. X        dataline = NUMDATALINES;
  744. X        }
  745. X
  746. X        else if ( fullspd )
  747. X        place_state( state, ds, totaltrans );
  748. X
  749. X    else if ( ds == end_of_buffer_state )
  750. X        /* special case this state to make sure it does what it's
  751. X         * supposed to, i.e., jam on end-of-buffer
  752. X         */
  753. X        stack1( ds, 0, 0, JAMSTATE );
  754. X
  755. X    else /* normal, compressed state */
  756. X        {
  757. X        /* determine which destination state is the most common, and
  758. X         * how many transitions to it there are
  759. X         */
  760. X
  761. X        comfreq = 0;
  762. X        comstate = 0;
  763. X
  764. X        for ( i = 1; i <= targptr; ++i )
  765. X        if ( targfreq[i] > comfreq )
  766. X            {
  767. X            comfreq = targfreq[i];
  768. X            comstate = targstate[i];
  769. X            }
  770. X
  771. X        bldtbl( state, ds, totaltrans, comstate, comfreq );
  772. X        }
  773. X    }
  774. X
  775. X    if ( fulltbl )
  776. X    dataend();
  777. X
  778. X    else if ( ! fullspd )
  779. X    {
  780. X    cmptmps();  /* create compressed template entries */
  781. X
  782. X    /* create tables for all the states with only one out-transition */
  783. X    while ( onesp > 0 )
  784. X        {
  785. X        mk1tbl( onestate[onesp], onesym[onesp], onenext[onesp],
  786. X            onedef[onesp] );
  787. X        --onesp;
  788. X        }
  789. X
  790. X    mkdeftbl();
  791. X    }
  792. X    }
  793. X
  794. X
  795. X/* snstods - converts a set of ndfa states into a dfa state
  796. X *
  797. X * synopsis
  798. X *    int sns[numstates], numstates, newds, accset[num_rules + 1], nacc, hashval;
  799. X *    int snstods();
  800. X *    is_new_state = snstods( sns, numstates, accset, nacc, hashval, &newds );
  801. X *
  802. X * on return, the dfa state number is in newds.
  803. X */
  804. X
  805. Xint snstods( sns, numstates, accset, nacc, hashval, newds_addr )
  806. Xint sns[], numstates, accset[], nacc, hashval, *newds_addr;
  807. X
  808. X    {
  809. X    int didsort = 0;
  810. X    register int i, j;
  811. X    int newds, *oldsns;
  812. X
  813. X    for ( i = 1; i <= lastdfa; ++i )
  814. X    if ( hashval == dhash[i] )
  815. X        {
  816. X        if ( numstates == dfasiz[i] )
  817. X        {
  818. X        oldsns = dss[i];
  819. X
  820. X        if ( ! didsort )
  821. X            {
  822. X            /* we sort the states in sns so we can compare it to
  823. X             * oldsns quickly.  we use bubble because there probably
  824. X             * aren't very many states
  825. X             */
  826. X            bubble( sns, numstates );
  827. X            didsort = 1;
  828. X            }
  829. X
  830. X        for ( j = 1; j <= numstates; ++j )
  831. X            if ( sns[j] != oldsns[j] )
  832. X            break;
  833. X
  834. X        if ( j > numstates )
  835. X            {
  836. X            ++dfaeql;
  837. X            *newds_addr = i;
  838. X            return ( 0 );
  839. X            }
  840. X
  841. X        ++hshcol;
  842. X        }
  843. X
  844. X        else
  845. X        ++hshsave;
  846. X        }
  847. X
  848. X    /* make a new dfa */
  849. X
  850. X    if ( ++lastdfa >= current_max_dfas )
  851. X    increase_max_dfas();
  852. X
  853. X    newds = lastdfa;
  854. X
  855. X    dss[newds] = (int *) malloc( (unsigned) ((numstates + 1) * sizeof( int )) );
  856. X
  857. X    if ( ! dss[newds] )
  858. X    flexfatal( "dynamic memory failure in snstods()" );
  859. X
  860. X    /* if we haven't already sorted the states in sns, we do so now, so that
  861. X     * future comparisons with it can be made quickly
  862. X     */
  863. X
  864. X    if ( ! didsort )
  865. X    bubble( sns, numstates );
  866. X
  867. X    for ( i = 1; i <= numstates; ++i )
  868. X    dss[newds][i] = sns[i];
  869. X
  870. X    dfasiz[newds] = numstates;
  871. X    dhash[newds] = hashval;
  872. X
  873. X    if ( nacc == 0 )
  874. X    {
  875. X    if ( reject )
  876. X        dfaacc[newds].dfaacc_set = (int *) 0;
  877. X    else
  878. X        dfaacc[newds].dfaacc_state = 0;
  879. X
  880. X    accsiz[newds] = 0;
  881. X    }
  882. X
  883. X    else if ( reject )
  884. X    {
  885. X    /* we sort the accepting set in increasing order so the disambiguating
  886. X     * rule that the first rule listed is considered match in the event of
  887. X     * ties will work.  We use a bubble sort since the list is probably
  888. X     * quite small.
  889. X     */
  890. X
  891. X    bubble( accset, nacc );
  892. X
  893. X    dfaacc[newds].dfaacc_set =
  894. X        (int *) malloc( (unsigned) ((nacc + 1) * sizeof( int )) );
  895. X
  896. X    if ( ! dfaacc[newds].dfaacc_set )
  897. X        flexfatal( "dynamic memory failure in snstods()" );
  898. X
  899. X    /* save the accepting set for later */
  900. X    for ( i = 1; i <= nacc; ++i )
  901. X        dfaacc[newds].dfaacc_set[i] = accset[i];
  902. X
  903. X    accsiz[newds] = nacc;
  904. X    }
  905. X
  906. X    else
  907. X    { /* find lowest numbered rule so the disambiguating rule will work */
  908. X    j = num_rules + 1;
  909. X
  910. X    for ( i = 1; i <= nacc; ++i )
  911. X        if ( accset[i] < j )
  912. X        j = accset[i];
  913. X
  914. X    dfaacc[newds].dfaacc_state = j;
  915. X    }
  916. X
  917. X    *newds_addr = newds;
  918. X
  919. X    return ( 1 );
  920. X    }
  921. X
  922. X
  923. X/* symfollowset - follow the symbol transitions one step
  924. X *
  925. X * synopsis
  926. X *    int ds[current_max_dfa_size], dsize, transsym;
  927. X *    int nset[current_max_dfa_size], numstates;
  928. X *    numstates = symfollowset( ds, dsize, transsym, nset );
  929. X */
  930. X
  931. Xint symfollowset( ds, dsize, transsym, nset )
  932. Xint ds[], dsize, transsym, nset[];
  933. X
  934. X    {
  935. X    int ns, tsp, sym, i, j, lenccl, ch, numstates;
  936. X    int ccllist;
  937. X
  938. X    numstates = 0;
  939. X
  940. X    for ( i = 1; i <= dsize; ++i )
  941. X    { /* for each nfa state ns in the state set of ds */
  942. X    ns = ds[i];
  943. X    sym = transchar[ns];
  944. X    tsp = trans1[ns];
  945. X
  946. X    if ( sym < 0 )
  947. X        { /* it's a character class */
  948. X        sym = -sym;
  949. X        ccllist = cclmap[sym];
  950. X        lenccl = ccllen[sym];
  951. X
  952. X        if ( cclng[sym] )
  953. X        {
  954. X        for ( j = 0; j < lenccl; ++j )
  955. X            { /* loop through negated character class */
  956. X            ch = ccltbl[ccllist + j];
  957. X
  958. X            if ( ch == 0 )
  959. X            ch = NUL_ec;
  960. X
  961. X            if ( ch > transsym )
  962. X            break;    /* transsym isn't in negated ccl */
  963. X
  964. X            else if ( ch == transsym )
  965. X            /* next 2 */ goto bottom;
  966. X            }
  967. X
  968. X        /* didn't find transsym in ccl */
  969. X        nset[++numstates] = tsp;
  970. X        }
  971. X
  972. X        else
  973. X        for ( j = 0; j < lenccl; ++j )
  974. X            {
  975. X            ch = ccltbl[ccllist + j];
  976. X
  977. X            if ( ch == 0 )
  978. X            ch = NUL_ec;
  979. X
  980. X            if ( ch > transsym )
  981. X            break;
  982. X
  983. X            else if ( ch == transsym )
  984. X            {
  985. X            nset[++numstates] = tsp;
  986. X            break;
  987. X            }
  988. X            }
  989. X        }
  990. X
  991. X    else if ( sym >= 'A' && sym <= 'Z' && caseins )
  992. X        flexfatal( "consistency check failed in symfollowset" );
  993. X
  994. X    else if ( sym == SYM_EPSILON )
  995. X        { /* do nothing */
  996. X        }
  997. X
  998. X    else if ( abs( ecgroup[sym] ) == transsym )
  999. X        nset[++numstates] = tsp;
  1000. X
  1001. Xbottom:
  1002. X    ;
  1003. X    }
  1004. X
  1005. X    return ( numstates );
  1006. X    }
  1007. X
  1008. X
  1009. X/* sympartition - partition characters with same out-transitions
  1010. X *
  1011. X * synopsis
  1012. X *    integer ds[current_max_dfa_size], numstates, duplist[numecs];
  1013. X *    symlist[numecs];
  1014. X *    sympartition( ds, numstates, symlist, duplist );
  1015. X */
  1016. X
  1017. Xvoid sympartition( ds, numstates, symlist, duplist )
  1018. Xint ds[], numstates, duplist[];
  1019. Xint symlist[];
  1020. X
  1021. X    {
  1022. X    int tch, i, j, k, ns, dupfwd[CSIZE + 1], lenccl, cclp, ich;
  1023. X
  1024. X    /* partitioning is done by creating equivalence classes for those
  1025. X     * characters which have out-transitions from the given state.  Thus
  1026. X     * we are really creating equivalence classes of equivalence classes.
  1027. X     */
  1028. X
  1029. X    for ( i = 1; i <= numecs; ++i )
  1030. X    { /* initialize equivalence class list */
  1031. X    duplist[i] = i - 1;
  1032. X    dupfwd[i] = i + 1;
  1033. X    }
  1034. X
  1035. X    duplist[1] = NIL;
  1036. X    dupfwd[numecs] = NIL;
  1037. X
  1038. X    for ( i = 1; i <= numstates; ++i )
  1039. X    {
  1040. X    ns = ds[i];
  1041. X    tch = transchar[ns];
  1042. X
  1043. X    if ( tch != SYM_EPSILON )
  1044. X        {
  1045. X        if ( tch < -lastccl || tch > csize )
  1046. X        {
  1047. X        if ( tch > csize && tch <= CSIZE )
  1048. X            flexerror( "scanner requires -8 flag" );
  1049. X
  1050. X        else
  1051. X            flexfatal(
  1052. X            "bad transition character detected in sympartition()" );
  1053. X        }
  1054. X
  1055. X        if ( tch >= 0 )
  1056. X        { /* character transition */
  1057. X        /* abs() needed for fake %t ec's */
  1058. X        int ec = abs( ecgroup[tch] );
  1059. X
  1060. X        mkechar( ec, dupfwd, duplist );
  1061. X        symlist[ec] = 1;
  1062. X        }
  1063. X
  1064. X        else
  1065. X        { /* character class */
  1066. X        tch = -tch;
  1067. X
  1068. X        lenccl = ccllen[tch];
  1069. X        cclp = cclmap[tch];
  1070. X        mkeccl( ccltbl + cclp, lenccl, dupfwd, duplist, numecs,
  1071. X            NUL_ec );
  1072. X
  1073. X        if ( cclng[tch] )
  1074. X            {
  1075. X            j = 0;
  1076. X
  1077. X            for ( k = 0; k < lenccl; ++k )
  1078. X            {
  1079. X            ich = ccltbl[cclp + k];
  1080. X
  1081. X            if ( ich == 0 )
  1082. X                ich = NUL_ec;
  1083. X
  1084. X            for ( ++j; j < ich; ++j )
  1085. X                symlist[j] = 1;
  1086. X            }
  1087. X
  1088. X            for ( ++j; j <= numecs; ++j )
  1089. X            symlist[j] = 1;
  1090. X            }
  1091. X
  1092. X        else
  1093. X            for ( k = 0; k < lenccl; ++k )
  1094. X            {
  1095. X            ich = ccltbl[cclp + k];
  1096. X
  1097. X            if ( ich == 0 )
  1098. X                ich = NUL_ec;
  1099. X
  1100. X            symlist[ich] = 1;
  1101. X            }
  1102. X        }
  1103. X        }
  1104. X    }
  1105. X    }
  1106. END_OF_FILE
  1107. if test 26919 -ne `wc -c <'dfa.c'`; then
  1108.     echo shar: \"'dfa.c'\" unpacked with wrong size!
  1109. fi
  1110. # end of 'dfa.c'
  1111. fi
  1112. if test -f 'flex.Doc' -a "${1}" != "-c" ; then 
  1113.   echo shar: Will not clobber existing file \"'flex.Doc'\"
  1114. else
  1115. echo shar: Extracting \"'flex.Doc'\" \(25372 characters\)
  1116. sed "s/^X//" >'flex.Doc' <<'END_OF_FILE'
  1117. X
  1118. X
  1119. X
  1120. XFLEX(1)                   USER COMMANDS                   FLEX(1)
  1121. X
  1122. X
  1123. X
  1124. XNAME
  1125. X     flex - fast lexical analyzer generator
  1126. X
  1127. XSYNOPSIS
  1128. X     flex [-bcdfinpstvFILT8 -C[efmF] -Sskeleton] [filename ...]
  1129. X
  1130. XDESCRIPTION
  1131. X     flex is a  tool  for  generating  scanners:  programs  which
  1132. X     recognized  lexical  patterns in text.  flex reads the given
  1133. X     input files, or its standard input  if  no  file  names  are
  1134. X     given,  for  a  description  of  a scanner to generate.  The
  1135. X     description is in the form of pairs of  regular  expressions
  1136. X     and  C  code,  called  rules.  flex  generates as output a C
  1137. X     source file, lex.yy.c, which defines a routine yylex(). This
  1138. X     file is compiled and linked with the -lfl library to produce
  1139. X     an executable.  When the executable is run, it analyzes  its
  1140. X     input  for occurrences of the regular expressions.  Whenever
  1141. X     it finds one, it executes the corresponding C code.
  1142. X
  1143. X     For full documentation, see flexdoc(1). This manual entry is
  1144. X     intended for use as a quick reference.
  1145. X
  1146. XOPTIONS
  1147. X     flex has the following options:
  1148. X
  1149. X     -b   Generate  backtracking  information  to  lex.backtrack.
  1150. X          This  is  a  list of scanner states which require back-
  1151. X          tracking and the input characters on which they do  so.
  1152. X          By adding rules one can remove backtracking states.  If
  1153. X          all backtracking states are eliminated and -f or -F  is
  1154. X          used, the generated scanner will run faster.
  1155. X
  1156. X     -c   is a do-nothing, deprecated option included  for  POSIX
  1157. X          compliance.
  1158. X
  1159. X          NOTE: in previous releases of flex -c specified  table-
  1160. X          compression  options.   This functionality is now given
  1161. X          by the -C flag.  To ease the the impact of this change,
  1162. X          when  flex encounters -c, it currently issues a warning
  1163. X          message and assumes that -C was  desired  instead.   In
  1164. X          the future this "promotion" of -c to -C will go away in
  1165. X          the name of full POSIX  compliance  (unless  the  POSIX
  1166. X          meaning is removed first).
  1167. X
  1168. X     -d   makes the generated scanner run in debug  mode.   When-
  1169. X          ever   a   pattern   is   recognized   and  the  global
  1170. X          yy_flex_debug is non-zero (which is the  default),  the
  1171. X          scanner will write to stderr a line of the form:
  1172. X
  1173. X              --accepting rule at line 53 ("the matched text")
  1174. X
  1175. X          The line number refers to the location of the  rule  in
  1176. X
  1177. X
  1178. X
  1179. XVersion 2.3         Last change: 26 May 1990                    1
  1180. X
  1181. X
  1182. X
  1183. X
  1184. X
  1185. X
  1186. XFLEX(1)                   USER COMMANDS                   FLEX(1)
  1187. X
  1188. X
  1189. X
  1190. X          the  file defining the scanner (i.e., the file that was
  1191. X          fed to flex).  Messages are  also  generated  when  the
  1192. X          scanner  backtracks,  accepts the default rule, reaches
  1193. X          the end of its input buffer (or encounters a  NUL;  the
  1194. X          two  look  the same as far as the scanner's concerned),
  1195. X          or reaches an end-of-file.
  1196. X
  1197. X     -f   specifies (take your pick) full table or fast  scanner.
  1198. X          No  table compression is done.  The result is large but
  1199. X          fast.  This option is equivalent to -Cf (see below).
  1200. X
  1201. X     -i   instructs flex to generate a case-insensitive  scanner.
  1202. X          The  case  of  letters given in the flex input patterns
  1203. X          will be ignored,  and  tokens  in  the  input  will  be
  1204. X          matched  regardless of case.  The matched text given in
  1205. X          yytext will have the preserved case (i.e., it will  not
  1206. X          be folded).
  1207. X
  1208. X     -n   is another do-nothing, deprecated option included  only
  1209. X          for POSIX compliance.
  1210. X
  1211. X     -p   generates a performance report to stderr.   The  report
  1212. X          consists  of  comments  regarding  features of the flex
  1213. X          input file which will cause a loss  of  performance  in
  1214. X          the resulting scanner.
  1215. X
  1216. X     -s   causes the default rule (that unmatched  scanner  input
  1217. X          is  echoed to stdout) to be suppressed.  If the scanner
  1218. X          encounters input that does not match any of its  rules,
  1219. X          it aborts with an error.
  1220. X
  1221. X     -t   instructs flex to write the  scanner  it  generates  to
  1222. X          standard output instead of lex.yy.c.
  1223. X
  1224. X     -v   specifies that flex should write to stderr a summary of
  1225. X          statistics regarding the scanner it generates.
  1226. X
  1227. X     -F   specifies that the fast  scanner  table  representation
  1228. X          should  be  used.  This representation is about as fast
  1229. X          as the full table representation  (-f),  and  for  some
  1230. X          sets  of patterns will be considerably smaller (and for
  1231. X          others, larger).  See flexdoc(1) for details.
  1232. X
  1233. X          This option is equivalent to -CF (see below).
  1234. X
  1235. X     -I   instructs flex to generate an interactive scanner, that
  1236. X          is, a scanner which stops immediately rather than look-
  1237. X          ing ahead if it knows that the currently  scanned  text
  1238. X          cannot  be  part  of a longer rule's match.  Again, see
  1239. X          flexdoc(1) for details.
  1240. X
  1241. X          Note, -I cannot be used in  conjunction  with  full  or
  1242. X
  1243. X
  1244. X
  1245. XVersion 2.3         Last change: 26 May 1990                    2
  1246. X
  1247. X
  1248. X
  1249. X
  1250. X
  1251. X
  1252. XFLEX(1)                   USER COMMANDS                   FLEX(1)
  1253. X
  1254. X
  1255. X
  1256. X          fast tables, i.e., the -f, -F, -Cf, or -CF flags.
  1257. X
  1258. X     -L   instructs flex not  to  generate  #line  directives  in
  1259. X          lex.yy.c. The default is to generate such directives so
  1260. X          error messages in the actions will be correctly located
  1261. X          with  respect  to the original flex input file, and not
  1262. X          to the fairly meaningless line numbers of lex.yy.c.
  1263. X
  1264. X     -T   makes flex run in trace mode.  It will generate  a  lot
  1265. X          of  messages to stdout concerning the form of the input
  1266. X          and the resultant non-deterministic  and  deterministic
  1267. X          finite  automata.   This  option  is  mostly for use in
  1268. X          maintaining flex.
  1269. X
  1270. X     -8   instructs flex to generate an 8-bit scanner.   On  some
  1271. X          sites,  this is the default.  On others, the default is
  1272. X          7-bit characters.  To see which is the case, check  the
  1273. X          verbose  (-v) output for "equivalence classes created".
  1274. X          If the denominator of the number shown is 128, then  by
  1275. X          default  flex is generating 7-bit characters.  If it is
  1276. X          256, then the default is 8-bit characters.
  1277. X
  1278. X     -C[efmF]
  1279. X          controls the degree of table compression.
  1280. X
  1281. X          -Ce directs  flex  to  construct  equivalence  classes,
  1282. X          i.e.,  sets  of characters which have identical lexical
  1283. X          properties.  Equivalence classes usually give  dramatic
  1284. X          reductions  in the final table/object file sizes (typi-
  1285. X          cally  a  factor  of  2-5)   and   are   pretty   cheap
  1286. X          performance-wise   (one  array  look-up  per  character
  1287. X          scanned).
  1288. X
  1289. X          -Cf specifies that the full scanner  tables  should  be
  1290. X          generated - flex should not compress the tables by tak-
  1291. X          ing advantages of similar transition functions for dif-
  1292. X          ferent states.
  1293. X
  1294. X          -CF specifies that the alternate fast scanner represen-
  1295. X          tation (described in flexdoc(1)) should be used.
  1296. X
  1297. X          -Cm directs flex to construct meta-equivalence classes,
  1298. X          which  are  sets of equivalence classes (or characters,
  1299. X          if equivalence classes are not  being  used)  that  are
  1300. X          commonly  used  together.  Meta-equivalence classes are
  1301. X          often a big win when using compressed tables, but  they
  1302. X          have  a  moderate  performance  impact (one or two "if"
  1303. X          tests and one array look-up per character scanned).
  1304. X
  1305. X          A lone -C specifies that the scanner tables  should  be
  1306. X          compressed  but  neither  equivalence classes nor meta-
  1307. X          equivalence classes should be used.
  1308. X
  1309. X
  1310. X
  1311. XVersion 2.3         Last change: 26 May 1990                    3
  1312. X
  1313. X
  1314. X
  1315. X
  1316. X
  1317. X
  1318. XFLEX(1)                   USER COMMANDS                   FLEX(1)
  1319. X
  1320. X
  1321. X
  1322. X          The options -Cf or  -CF  and  -Cm  do  not  make  sense
  1323. X          together - there is no opportunity for meta-equivalence
  1324. X          classes if the table is not being  compressed.   Other-
  1325. X          wise the options may be freely mixed.
  1326. X
  1327. X          The default setting is -Cem, which specifies that  flex
  1328. X          should   generate   equivalence   classes   and   meta-
  1329. X          equivalence classes.  This setting provides the highest
  1330. X          degree   of  table  compression.   You  can  trade  off
  1331. X          faster-executing scanners at the cost of larger  tables
  1332. X          with the following generally being true:
  1333. X
  1334. X              slowest & smallest
  1335. X                    -Cem
  1336. X                    -Cm
  1337. X                    -Ce
  1338. X                    -C
  1339. X                    -C{f,F}e
  1340. X                    -C{f,F}
  1341. X              fastest & largest
  1342. X
  1343. X
  1344. X          -C options are not cumulative;  whenever  the  flag  is
  1345. X          encountered, the previous -C settings are forgotten.
  1346. X
  1347. X     -Sskeleton_file
  1348. X          overrides the default skeleton  file  from  which  flex
  1349. X          constructs its scanners.  You'll never need this option
  1350. X          unless you are doing flex maintenance or development.
  1351. X
  1352. XSUMMARY OF FLEX REGULAR EXPRESSIONS
  1353. X     The patterns in the input are written using an extended  set
  1354. X     of regular expressions.  These are:
  1355. X
  1356. X         x          match the character 'x'
  1357. X         .          any character except newline
  1358. X         [xyz]      a "character class"; in this case, the pattern
  1359. X                      matches either an 'x', a 'y', or a 'z'
  1360. X         [abj-oZ]   a "character class" with a range in it; matches
  1361. X                      an 'a', a 'b', any letter from 'j' through 'o',
  1362. X                      or a 'Z'
  1363. X         [^A-Z]     a "negated character class", i.e., any character
  1364. X                      but those in the class.  In this case, any
  1365. X                      character EXCEPT an uppercase letter.
  1366. X         [^A-Z\n]   any character EXCEPT an uppercase letter or
  1367. X                      a newline
  1368. X         r*         zero or more r's, where r is any regular expression
  1369. X         r+         one or more r's
  1370. X         r?         zero or one r's (that is, "an optional r")
  1371. X         r{2,5}     anywhere from two to five r's
  1372. X         r{2,}      two or more r's
  1373. X         r{4}       exactly 4 r's
  1374. X
  1375. X
  1376. X
  1377. XVersion 2.3         Last change: 26 May 1990                    4
  1378. X
  1379. X
  1380. X
  1381. X
  1382. X
  1383. X
  1384. XFLEX(1)                   USER COMMANDS                   FLEX(1)
  1385. X
  1386. X
  1387. X
  1388. X         {name}     the expansion of the "name" definition
  1389. X                    (see above)
  1390. X         "[xyz]\"foo"
  1391. X                    the literal string: [xyz]"foo
  1392. X         \X         if X is an 'a', 'b', 'f', 'n', 'r', 't', or 'v',
  1393. X                      then the ANSI-C interpretation of \x.
  1394. X                      Otherwise, a literal 'X' (used to escape
  1395. X                      operators such as '*')
  1396. X         \123       the character with octal value 123
  1397. X         \x2a       the character with hexadecimal value 2a
  1398. X         (r)        match an r; parentheses are used to override
  1399. X                      precedence (see below)
  1400. X
  1401. X
  1402. X         rs         the regular expression r followed by the
  1403. X                      regular expression s; called "concatenation"
  1404. X
  1405. X
  1406. X         r|s        either an r or an s
  1407. X
  1408. X
  1409. X         r/s        an r but only if it is followed by an s.  The
  1410. X                      s is not part of the matched text.  This type
  1411. X                      of pattern is called as "trailing context".
  1412. X         ^r         an r, but only at the beginning of a line
  1413. X         r$         an r, but only at the end of a line.  Equivalent
  1414. X                      to "r/\n".
  1415. X
  1416. X
  1417. X         <s>r       an r, but only in start condition s (see
  1418. X                    below for discussion of start conditions)
  1419. X         <s1,s2,s3>r
  1420. X                    same, but in any of start conditions s1,
  1421. X                    s2, or s3
  1422. X
  1423. X
  1424. X         <<EOF>>    an end-of-file
  1425. X         <s1,s2><<EOF>>
  1426. X                    an end-of-file when in start condition s1 or s2
  1427. X
  1428. X     The regular expressions listed above are  grouped  according
  1429. X     to  precedence, from highest precedence at the top to lowest
  1430. X     at the bottom.   Those  grouped  together  have  equal  pre-
  1431. X     cedence.
  1432. X
  1433. X     Some notes on patterns:
  1434. X
  1435. X     -    Negated character classes match  newlines  unless  "\n"
  1436. X          (or  an equivalent escape sequence) is one of the char-
  1437. X          acters explicitly  present  in  the  negated  character
  1438. X          class (e.g., "[^A-Z\n]").
  1439. X
  1440. X
  1441. X
  1442. X
  1443. XVersion 2.3         Last change: 26 May 1990                    5
  1444. X
  1445. X
  1446. X
  1447. X
  1448. X
  1449. X
  1450. XFLEX(1)                   USER COMMANDS                   FLEX(1)
  1451. X
  1452. X
  1453. X
  1454. X     -    A rule can have at most one instance of  trailing  con-
  1455. X          text (the '/' operator or the '$' operator).  The start
  1456. X          condition, '^', and "<<EOF>>" patterns can  only  occur
  1457. X          at the beginning of a pattern, and, as well as with '/'
  1458. X          and '$', cannot be  grouped  inside  parentheses.   The
  1459. X          following are all illegal:
  1460. X
  1461. X              foo/bar$
  1462. X              foo|(bar$)
  1463. X              foo|^bar
  1464. X              <sc1>foo<sc2>bar
  1465. X
  1466. X
  1467. XSUMMARY OF SPECIAL ACTIONS
  1468. X     In addition to arbitrary C code, the following can appear in
  1469. X     actions:
  1470. X
  1471. X     -    ECHO copies yytext to the scanner's output.
  1472. X
  1473. X     -    BEGIN followed by the name of a start condition  places
  1474. X          the scanner in the corresponding start condition.
  1475. X
  1476. X     -    REJECT directs the scanner to proceed on to the "second
  1477. X          best"  rule which matched the input (or a prefix of the
  1478. X          input).  yytext and yyleng are  set  up  appropriately.
  1479. X          Note that REJECT is a particularly expensive feature in
  1480. X          terms scanner performance; if it is used in any of  the
  1481. X          scanner's   actions  it  will  slow  down  all  of  the
  1482. X          scanner's matching.  Furthermore, REJECT cannot be used
  1483. X          with the -f or -F options.
  1484. X
  1485. X          Note also that unlike the other special actions, REJECT
  1486. X          is  a  branch;  code  immediately  following  it in the
  1487. X          action will not be executed.
  1488. X
  1489. X     -    yymore() tells  the  scanner  that  the  next  time  it
  1490. X          matches  a  rule,  the  corresponding  token  should be
  1491. X          appended onto the current value of yytext  rather  than
  1492. X          replacing it.
  1493. X
  1494. X     -    yyless(n) returns all but the first n characters of the
  1495. X          current token back to the input stream, where they will
  1496. X          be rescanned when the scanner looks for the next match.
  1497. X          yytext  and  yyleng  are  adjusted appropriately (e.g.,
  1498. X          yyleng will now be equal to n ).
  1499. X
  1500. X     -    unput(c) puts the  character  c  back  onto  the  input
  1501. X          stream.  It will be the next character scanned.
  1502. X
  1503. X     -    input() reads the next character from the input  stream
  1504. X          (this  routine  is  called  yyinput() if the scanner is
  1505. X          compiled using C++).
  1506. X
  1507. X
  1508. X
  1509. XVersion 2.3         Last change: 26 May 1990                    6
  1510. X
  1511. X
  1512. X
  1513. X
  1514. X
  1515. X
  1516. XFLEX(1)                   USER COMMANDS                   FLEX(1)
  1517. X
  1518. X
  1519. X
  1520. X     -    yyterminate() can be used in lieu of a return statement
  1521. X          in  an action.  It terminates the scanner and returns a
  1522. X          0 to the scanner's caller, indicating "all done".
  1523. X
  1524. X          By default, yyterminate() is also called when  an  end-
  1525. X          of-file is encountered.  It is a macro and may be rede-
  1526. X          fined.
  1527. X
  1528. X     -    YY_NEW_FILE is an  action  available  only  in  <<EOF>>
  1529. X          rules.   It  means "Okay, I've set up a new input file,
  1530. X          continue scanning".
  1531. X
  1532. X     -    yy_create_buffer( file, size ) takes a FILE pointer and
  1533. X          an integer size. It returns a YY_BUFFER_STATE handle to
  1534. X          a new input buffer  large  enough  to  accomodate  size
  1535. X          characters and associated with the given file.  When in
  1536. X          doubt, use YY_BUF_SIZE for the size.
  1537. X
  1538. X     -    yy_switch_to_buffer(   new_buffer   )   switches    the
  1539. X          scanner's  processing to scan for tokens from the given
  1540. X          buffer, which must be a YY_BUFFER_STATE.
  1541. X
  1542. X     -    yy_delete_buffer( buffer ) deletes the given buffer.
  1543. X
  1544. XVALUES AVAILABLE TO THE USER
  1545. X     -    char *yytext holds the text of the current  token.   It
  1546. X          may not be modified.
  1547. X
  1548. X     -    int yyleng holds the length of the current  token.   It
  1549. X          may not be modified.
  1550. X
  1551. X     -    FILE *yyin is the file  which  by  default  flex  reads
  1552. X          from.   It  may  be  redefined  but doing so only makes
  1553. X          sense before scanning begins.  Changing it in the  mid-
  1554. X          dle of scanning will have unexpected results since flex
  1555. X          buffers its input.  Once scanning terminates because an
  1556. X          end-of-file   has   been  seen,  void  yyrestart(  FILE
  1557. X          *new_file ) may be called to  point  yyin  at  the  new
  1558. X          input file.
  1559. X
  1560. X     -    FILE *yyout is the file to which ECHO actions are done.
  1561. X          It can be reassigned by the user.
  1562. X
  1563. X     -    YY_CURRENT_BUFFER returns a YY_BUFFER_STATE  handle  to
  1564. X          the current buffer.
  1565. X
  1566. XMACROS THE USER CAN REDEFINE
  1567. X     -    YY_DECL controls how the scanning routine is  declared.
  1568. X          By  default, it is "int yylex()", or, if prototypes are
  1569. X          being used, "int yylex(void)".  This definition may  be
  1570. X          changed  by  redefining the "YY_DECL" macro.  Note that
  1571. X          if you give arguments to the scanning routine  using  a
  1572. X
  1573. X
  1574. X
  1575. XVersion 2.3         Last change: 26 May 1990                    7
  1576. X
  1577. X
  1578. X
  1579. X
  1580. X
  1581. X
  1582. XFLEX(1)                   USER COMMANDS                   FLEX(1)
  1583. X
  1584. X
  1585. X
  1586. X          K&R-style/non-prototyped function declaration, you must
  1587. X          terminate the definition with a semi-colon (;).
  1588. X
  1589. X     -    The nature of how the scanner gets  its  input  can  be
  1590. X          controlled    by   redefining   the   YY_INPUT   macro.
  1591. X          YY_INPUT's         calling         sequence          is
  1592. X          "YY_INPUT(buf,result,max_size)".    Its  action  is  to
  1593. X          place up to max_size characters in the character  array
  1594. X          buf  and  return  in the integer variable result either
  1595. X          the number of characters read or the  constant  YY_NULL
  1596. X          (0  on  Unix  systems)  to  indicate  EOF.  The default
  1597. X          YY_INPUT reads from the global file-pointer "yyin".   A
  1598. X          sample  redefinition  of  YY_INPUT  (in the definitions
  1599. X          section of the input file):
  1600. X
  1601. X              %{
  1602. X              #undef YY_INPUT
  1603. X              #define YY_INPUT(buf,result,max_size) \
  1604. X                  { \
  1605. X                  int c = getchar(); \
  1606. X                  result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
  1607. X                  }
  1608. X              %}
  1609. X
  1610. X
  1611. X     -    When the scanner  receives  an  end-of-file  indication
  1612. X          from  YY_INPUT,  it  then checks the yywrap() function.
  1613. X          If yywrap() returns false (zero), then  it  is  assumed
  1614. X          that  the  function  has  gone ahead and set up yyin to
  1615. X          point to another input file,  and  scanning  continues.
  1616. X          If  it  returns  true (non-zero), then the scanner ter-
  1617. X          minates, returning 0 to its caller.
  1618. X
  1619. X          The default yywrap() always returns 1.   Presently,  to
  1620. X          redefine  it  you  must first "#undef yywrap", as it is
  1621. X          currently implemented as a macro.  It  is  likely  that
  1622. X          yywrap()  will  soon be defined to be a function rather
  1623. X          than a macro.
  1624. X
  1625. X     -    YY_USER_ACTION can be redefined to  provide  an  action
  1626. X          which  is  always  executed prior to the matched rule's
  1627. X          action.
  1628. X
  1629. X     -    The macro YY_USER_INIT may be redefined to  provide  an
  1630. X          action which is always executed before the first scan.
  1631. X
  1632. X     -    In the generated scanner, the actions are all  gathered
  1633. X          in  one  large  switch  statement  and  separated using
  1634. X          YY_BREAK, which may be redefined.  By  default,  it  is
  1635. X          simply  a  "break", to separate each rule's action from
  1636. X          the following rule's.
  1637. X
  1638. X
  1639. X
  1640. X
  1641. XVersion 2.3         Last change: 26 May 1990                    8
  1642. X
  1643. X
  1644. X
  1645. X
  1646. X
  1647. X
  1648. XFLEX(1)                   USER COMMANDS                   FLEX(1)
  1649. X
  1650. X
  1651. X
  1652. XFILES
  1653. X     flex.skel
  1654. X          skeleton scanner.
  1655. X
  1656. X     lex.yy.c
  1657. X          generated scanner (called lexyy.c on some systems).
  1658. X
  1659. X     lex.backtrack
  1660. X          backtracking information for -b flag (called lex.bck on
  1661. X          some systems).
  1662. X
  1663. X     -lfl library with which to link the scanners.
  1664. X
  1665. XSEE ALSO
  1666. X     flexdoc(1), lex(1), yacc(1), sed(1), awk(1).
  1667. X
  1668. X     M. E. Lesk and E. Schmidt, LEX - Lexical Analyzer Generator
  1669. X
  1670. XDIAGNOSTICS
  1671. X     reject_used_but_not_detected undefined or
  1672. X
  1673. X     yymore_used_but_not_detected undefined -  These  errors  can
  1674. X     occur  at compile time.  They indicate that the scanner uses
  1675. X     REJECT or yymore() but that flex failed to notice the  fact,
  1676. X     meaning that flex scanned the first two sections looking for
  1677. X     occurrences of these actions and failed  to  find  any,  but
  1678. X     somehow  you  snuck  some in (via a #include file, for exam-
  1679. X     ple).  Make an explicit reference to the action in your flex
  1680. X     input   file.    (Note  that  previously  flex  supported  a
  1681. X     %used/%unused mechanism for dealing with this problem;  this
  1682. X     feature  is  still supported but now deprecated, and will go
  1683. X     away soon unless the author hears from people who can  argue
  1684. X     compellingly that they need it.)
  1685. X
  1686. X     flex scanner jammed - a scanner compiled with -s has encoun-
  1687. X     tered  an  input  string  which wasn't matched by any of its
  1688. X     rules.
  1689. X
  1690. X     flex input buffer overflowed -  a  scanner  rule  matched  a
  1691. X     string  long enough to overflow the scanner's internal input
  1692. X     buffer  (16K   bytes   -   controlled   by   YY_BUF_MAX   in
  1693. X     "flex.skel").
  1694. X
  1695. X     scanner  requires  -8  flag  -  Your  scanner  specification
  1696. X     includes  recognizing  8-bit  characters  and  you  did  not
  1697. X     specify the -8 flag (and your site has  not  installed  flex
  1698. X     with -8 as the default).
  1699. X
  1700. X     fatal flex scanner internal error--end of  buffer  missed  -
  1701. X     This  can  occur  in  an  scanner which is reentered after a
  1702. X     long-jump has jumped out (or over) the scanner's  activation
  1703. X     frame.  Before reentering the scanner, use:
  1704. X
  1705. X
  1706. X
  1707. XVersion 2.3         Last change: 26 May 1990                    9
  1708. X
  1709. X
  1710. X
  1711. X
  1712. X
  1713. X
  1714. XFLEX(1)                   USER COMMANDS                   FLEX(1)
  1715. X
  1716. X
  1717. X
  1718. X         yyrestart( yyin );
  1719. X
  1720. X
  1721. X     too many %t classes! - You managed to put every single char-
  1722. X     acter  into  its  own %t class.  flex requires that at least
  1723. X     one of the classes share characters.
  1724. X
  1725. XAUTHOR
  1726. X     Vern Paxson, with the help of many ideas and  much  inspira-
  1727. X     tion from Van Jacobson.  Original version by Jef Poskanzer.
  1728. X
  1729. X     See flexdoc(1) for additional credits  and  the  address  to
  1730. X     send comments to.
  1731. X
  1732. XDEFICIENCIES / BUGS
  1733. X     Some trailing context patterns cannot  be  properly  matched
  1734. X     and  generate  warning  messages  ("Dangerous  trailing con-
  1735. X     text").  These are patterns where the ending  of  the  first
  1736. X     part  of  the rule matches the beginning of the second part,
  1737. X     such as "zx*/xy*", where the 'x*' matches  the  'x'  at  the
  1738. X     beginning  of  the  trailing  context.  (Note that the POSIX
  1739. X     draft states that the text matched by such patterns is unde-
  1740. X     fined.)
  1741. X
  1742. X     For some trailing context rules, parts  which  are  actually
  1743. X     fixed-length  are  not  recognized  as  such, leading to the
  1744. X     abovementioned performance loss.  In particular, parts using
  1745. X     '|'   or  {n}  (such  as  "foo{3}")  are  always  considered
  1746. X     variable-length.
  1747. X
  1748. X     Combining trailing context with the special '|'  action  can
  1749. X     result  in fixed trailing context being turned into the more
  1750. X     expensive variable trailing context.  For example, this hap-
  1751. X     pens in the following example:
  1752. X
  1753. X         %%
  1754. X         abc      |
  1755. X         xyz/def
  1756. X
  1757. X
  1758. X     Use of unput() invalidates yytext and yyleng.
  1759. X
  1760. X     Use of unput() to push back more text than was  matched  can
  1761. X     result  in the pushed-back text matching a beginning-of-line
  1762. X     ('^') rule even though it didn't come at  the  beginning  of
  1763. X     the line (though this is rare!).
  1764. X
  1765. X     Pattern-matching  of  NUL's  is  substantially  slower  than
  1766. X     matching other characters.
  1767. X
  1768. X     flex does not generate correct  #line  directives  for  code
  1769. X     internal to the scanner; thus, bugs in flex.skel yield bogus
  1770. X
  1771. X
  1772. X
  1773. XVersion 2.3         Last change: 26 May 1990                   10
  1774. X
  1775. X
  1776. X
  1777. X
  1778. X
  1779. X
  1780. XFLEX(1)                   USER COMMANDS                   FLEX(1)
  1781. X
  1782. X
  1783. X
  1784. X     line numbers.
  1785. X
  1786. X     Due to both buffering of input and  read-ahead,  you  cannot
  1787. X     intermix  calls to <stdio.h> routines, such as, for example,
  1788. X     getchar(), with flex rules and  expect  it  to  work.   Call
  1789. X     input() instead.
  1790. X
  1791. X     The total table entries listed by the -v flag  excludes  the
  1792. X     number  of  table  entries needed to determine what rule has
  1793. X     been matched.  The number of entries is equal to the  number
  1794. X     of  DFA states if the scanner does not use REJECT, and some-
  1795. X     what greater than the number of states if it does.
  1796. X
  1797. X     REJECT cannot be used with the -f or -F options.
  1798. X
  1799. X     Some of the macros, such as  yywrap(),  may  in  the  future
  1800. X     become  functions which live in the -lfl library.  This will
  1801. X     doubtless break a lot of  code,  but  may  be  required  for
  1802. X     POSIX-compliance.
  1803. X
  1804. X     The flex internal algorithms need documentation.
  1805. X
  1806. X
  1807. X
  1808. X
  1809. X
  1810. X
  1811. X
  1812. X
  1813. X
  1814. X
  1815. X
  1816. X
  1817. X
  1818. X
  1819. X
  1820. X
  1821. X
  1822. X
  1823. X
  1824. X
  1825. X
  1826. X
  1827. X
  1828. X
  1829. X
  1830. X
  1831. X
  1832. X
  1833. X
  1834. X
  1835. X
  1836. X
  1837. X
  1838. X
  1839. XVersion 2.3         Last change: 26 May 1990                   11
  1840. X
  1841. X
  1842. X
  1843. END_OF_FILE
  1844. if test 25372 -ne `wc -c <'flex.Doc'`; then
  1845.     echo shar: \"'flex.Doc'\" unpacked with wrong size!
  1846. fi
  1847. # end of 'flex.Doc'
  1848. fi
  1849. echo shar: End of archive 5 \(of 13\).
  1850. cp /dev/null ark5isdone
  1851. MISSING=""
  1852. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  1853.     if test ! -f ark${I}isdone ; then
  1854.     MISSING="${MISSING} ${I}"
  1855.     fi
  1856. done
  1857. if test "${MISSING}" = "" ; then
  1858.     echo You have unpacked all 13 archives.
  1859.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1860. else
  1861.     echo You still need to unpack the following archives:
  1862.     echo "        " ${MISSING}
  1863. fi
  1864. ##  End of shell archive.
  1865. exit 0
  1866. -- 
  1867. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  1868. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  1869. Post requests for sources, and general discussion to comp.sys.amiga.
  1870.